package com.doitdroid;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

import java.util.HashMap;

public class TaskProvider extends ContentProvider {

    private static final String TASK_TABLE_NAME = "task";

    private static HashMap<String, String> taskProjectionMap;

    private static final int ALL_TASKS = 1;
    private static final int LIST_TASKS = 2;
    private static final int LIST_TASK_ID =3;

    private static final UriMatcher sUriMatcher;

    private DatabaseHelper mOpenHelper;

    @Override
    public boolean onCreate() {
        mOpenHelper = new DatabaseHelper(getContext());
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        switch (sUriMatcher.match(uri)) {
        case LIST_TASKS:
            qb.setTables(TASK_TABLE_NAME);
            qb.setProjectionMap(taskProjectionMap);
            qb.appendWhere(TaskInfo.Task.LIST_ID + "=" + uri.getPathSegments().get(1));
            break;
        case LIST_TASK_ID:
            qb.setTables(TASK_TABLE_NAME);
            qb.setProjectionMap(taskProjectionMap);
            qb.appendWhere(TaskInfo.Task.LIST_ID + "=" + uri.getPathSegments().get(1));
            qb.appendWhere(" and " + TaskInfo.Task.TASK_ID + "=" + uri.getPathSegments().get(2));
            break;
        case ALL_TASKS:
            qb.setTables(TASK_TABLE_NAME);
            qb.setProjectionMap(taskProjectionMap);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        // If no sort order is specified use the default
        String orderBy;
        if (TextUtils.isEmpty(sortOrder)) {
            orderBy = TaskInfo.Task.DEFAULT_SORT_ORDER;
        } else {
            orderBy = sortOrder;
        }

        // Get the database and run the query
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);

        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    @Override
    public String getType(Uri uri) {
        switch (sUriMatcher.match(uri)) {
        case LIST_TASKS:
        case ALL_TASKS:
            return TaskInfo.Task.CONTENT_TYPE;

        case LIST_TASK_ID:
            return TaskInfo.Task.CONTENT_ITEM_TYPE;

        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues initialValues) {

        if (sUriMatcher.match(uri) != LIST_TASKS) {
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        ContentValues values;
        if (initialValues != null) {
            values = new ContentValues(initialValues);
        } else {
            values = new ContentValues();
        }

     // Make sure that the fields are all set
        if (values.containsKey(TaskInfo.Task.LIST_ID) == false) {
            int listID = Integer.parseInt(uri.getPathSegments().get(1));
        	values.put(TaskInfo.Task.LIST_ID, listID);
        }
        
        // Make sure that the fields are all set
        if (values.containsKey(TaskInfo.Task.NAME) == false) {
            String defaultTitle = getContext().getResources().getString(R.string.Empty);
        	values.put(TaskInfo.Task.NAME, defaultTitle);
        }

        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        long rowId = db.insert(TASK_TABLE_NAME, TaskInfo.Task.NAME, values);
        if (rowId > 0) {
            Uri noteUri = ContentUris.withAppendedId(TaskInfo.Task.CONTENT_URI, rowId);
            getContext().getContentResolver().notifyChange(noteUri, null);
            return noteUri;
        }

        throw new SQLException("Failed to insert row into " + uri);
    }

    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int count;
        switch (sUriMatcher.match(uri)) {
        case LIST_TASKS:
        case ALL_TASKS:
            count = db.delete(TASK_TABLE_NAME, where, whereArgs);
            break;

        case LIST_TASK_ID:
            String noteId = uri.getPathSegments().get(1);
            count = db.delete(TASK_TABLE_NAME, TaskInfo.Task._ID + "=" + noteId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int count;
        switch (sUriMatcher.match(uri)) {
        case LIST_TASKS:
        case ALL_TASKS:
            count = db.update(TASK_TABLE_NAME, values, where, whereArgs);
            break;

        case LIST_TASK_ID:
            String noteId = uri.getPathSegments().get(1);
            count = db.update(TASK_TABLE_NAME, values, TaskInfo.Task._ID + "=" + noteId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sUriMatcher.addURI(TaskInfo.AUTHORITY, "tasks", ALL_TASKS);
        sUriMatcher.addURI(TaskInfo.AUTHORITY, "tasks/#", LIST_TASKS);
        sUriMatcher.addURI(TaskInfo.AUTHORITY, "tasks/#/#", LIST_TASK_ID);

        taskProjectionMap = new HashMap<String, String>();
        taskProjectionMap.put(TaskInfo.Task.TASK_ID, TaskInfo.Task.TASK_ID);
        taskProjectionMap.put(TaskInfo.Task.NAME, TaskInfo.Task.NAME);
        taskProjectionMap.put(TaskInfo.Task.DUE_DATE, TaskInfo.Task.DUE_DATE);
        taskProjectionMap.put(TaskInfo.Task.LIST_ID, TaskInfo.Task.LIST_ID);
    }
}
